package com.example.demo3.controller;

import com.example.demo3.service.MyProcessService;
import com.example.demo3.service.MyTaskService;
import io.swagger.annotations.Api;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.repository.ProcessDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

@Api(value = "流程图")
@Slf4j
@RestController
public class ProcessController {
    @Autowired
    private MyProcessService processService;

    @Autowired
    private MyTaskService myTaskService;
    @Autowired
    private RepositoryService repositoryService;

    /**
     * 通过processDefinition.id和resType导出流程XML或图片资源
     * 导出流程定义图
     * 适用于流程管理或启动流程时查看已经部署的流程图，流程图不包括任务办理实际流转信息。
     * 使用流程定义(ProcessDefinition.id)，通过调用flowable 的RepositoryService来导出其流程定义的图片资源。
     *
     * @param id       processDefinition.id
     * @param resType  取值 “image/png”或“text/xml”
     * @param response
     * @throws Exception
     */
    @GetMapping(value = "/res/exp")
    @Operation(summary = "通过processDefinition.id和resType导出流程XML或图片资源")
    public void resourceRead(@RequestParam("id") String id, @RequestParam("resType") String resType, HttpServletResponse response) throws Exception {
        /** resType取值 “image/png”或“text/xml” **/
        InputStream resourceAsStream = processService.resourceRead(id, resType);
        byte[] b = new byte[1024];
        int len = -1;
        while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
            response.getOutputStream().write(b, 0, len);
        }
    }

    @GetMapping(value = "/res/exp1")
    @Operation(summary = "通过processDefinition.id和resType导出流程XML或图片资源")
    public void resourceRead1(@RequestParam("id") String id, @RequestParam("resType") String resType, HttpServletResponse response) throws Exception {
        /** resType取值 “image/png”或“text/xml” **/

        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(id).singleResult();
        String resourceName = "";
        if (resType.equals("image/png")) {
            resourceName = processDefinition.getDiagramResourceName();
        } else if (resType.equals("text/xml")) {
            resourceName = processDefinition.getResourceName();
        }
        InputStream resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), resourceName);

        response.setContentType("application/octet-stream");
        response.setHeader("Content-Disposition", "attachment; filename=" + processDefinition.getResourceName());
        byte[] b = new byte[1024];
        int len = -1;
        while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
            response.getOutputStream().write(b, 0, len);
        }
    }

    /**
     * 绘制强调当前节点的流程图
     * 绘制流程待办流图
     * 适用于查看待办任务列表时，绘制该任务的流程图，流程图可强调显示当前待办任务所处的流程节点。使用流程实例（processInstanceId）ID，通过调用flowable引擎来绘制流程图。
     */
    @GetMapping(value = "/process/diagram")
    @Operation(summary = "绘制强调当前节点的流程图")
    public void genProcessDiagram(@RequestParam("processInstanceId") String processInstanceId, HttpServletResponse httpServletResponse) throws Exception {
        InputStream resourceAsStream = myTaskService.genProcessDiagram(processInstanceId);
//        byte[] b = new byte[1024];
//        int len = -1;
//        while ((len = resourceAsStream.read(b, 0, 1024)) != -1) {
//            httpServletResponse.getOutputStream().write(b, 0, len);
//        }
        OutputStream os = null;
        try {
            BufferedImage image = ImageIO.read(resourceAsStream);
            httpServletResponse.setContentType("image/png");
            os = httpServletResponse.getOutputStream();
            if (image != null) {
                ImageIO.write(image, "png", os);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (resourceAsStream != null) {
                resourceAsStream.close();
            }
            if (os != null) {
                os.flush();
                os.close();
            }
        }
    }

    /**
     * 读取带跟踪的图片
     * <p>
     * 绘制流程已办流图
     * 适用于查看已办任务列表时，绘制该任务的流程图，流程图可强调显示任务办理实际经过的路径。使用流程实例（processInstanceId）ID，通过调用flowable引擎来绘制流程图。
     */
    @GetMapping(value = "/trace/photo")
    @Operation(summary = "读取带跟踪的图片")
    public void tracePhoto(@RequestParam("processInstanceId") String processInstanceId, HttpServletResponse response) throws Exception {
        InputStream inputStream = myTaskService.genTracePhoto(processInstanceId);

        // 输出资源内容到相应对象
//        byte[] b = new byte[1024];
//        int len;
//        while ((len = inputStream.read(b, 0, 1024)) != -1) {
//            response.getOutputStream().write(b, 0, len);
//        }

        OutputStream os = null;
        try {
            BufferedImage image = ImageIO.read(inputStream);
            response.setContentType("image/png");
            os = response.getOutputStream();
            if (image != null) {
                ImageIO.write(image, "png", os);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (inputStream != null) {
                inputStream.close();
            }
            if (os != null) {
                os.flush();
                os.close();
            }
        }


    }
}